package com.atguigu.gmall.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/api/payment/alipay")
public class AlipayController {

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${app_id}")
    private String app_id;


    //提交订单生成二维码
    @GetMapping("submit/{orderId}")
    @ResponseBody
    public String submitOrder(@PathVariable Long orderId) throws AlipayApiException {
        String from = alipayService.createAliPay(orderId);
        return from;
    }

    //同步回调
    @GetMapping("callback/return")
    public String callbackReturn() {
        //  可以修改订单状态了.
        //  http://payment.gmall.com/pay/success.html
        return "redirect:" + AlipayConfig.return_order_url;
    }

    //异步回调
    @PostMapping("callback/notify")
    @ResponseBody
    public String callbackNotify(@RequestParam Map<String, String> paramsMap) {

        System.out.println("胡汉三回来了...");
        //  Map<String, String> paramsMap = ... //将异步通知中收到的所有参数都存放到map中 ,验证前四步。
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        //  获取支付宝回调的订单编号
        String outTradeNo = paramsMap.get("out_trade_no");
        //  获取支付宝回调金额
        String totalAmount = paramsMap.get("total_amount");
        //  获取支付宝回调的app_id
        String appId = paramsMap.get("app_id");
        //  获取支付宝回调的notify_id
        String notifyId = paramsMap.get("notify_id");
        //获取支付宝回调trade status
        String tradeStatus = paramsMap.get("trade_status");

        //前四部
        if (signVerified) {
            //根据outTradeNo获取paymentInfo对象
            PaymentInfo paymentInfoQuery = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
            Boolean result = redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1462 * 60, TimeUnit.MINUTES);

            //判断
            if (paymentInfoQuery == null || new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount)) != 0 ||
                    !appId.equals(app_id) || !result) {

                return "failure";
            }
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                paymentService.paySuccess(outTradeNo, PaymentType.ALIPAY.name(), paramsMap);

                return "success";
            }
        } else {
            // TODO 验签失败则记录异常日志，并在response中返回failure.
            return "failure";
        }
        return "failure";
    }

    //  退款接口
    @GetMapping("refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable Long orderId) {
        //  调用服务层方法
        Boolean flag = this.alipayService.refund(orderId);
        return Result.ok(flag);

    }

    @GetMapping("closePay/{orderId}")
    @ResponseBody
    public Boolean closePay(@PathVariable Long orderId) {
        //调用服务处方法
        Boolean aBoolean = alipayService.closePay(orderId);
        return aBoolean;
    }

    @RequestMapping("checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable Long orderId){
        //  调用服务层方法.
        Boolean flag = this.alipayService.checkPayment(orderId);
        return flag;
    }

    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo) {
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (paymentInfo!=null){
            return paymentInfo;
        }
        return null;
    }
}
